namespace Nico {

    [GtkTemplate (ui="/de/grindhold/nico/ui/nico_client_app.ui")]
    public class ClientView : Gtk.ApplicationWindow {

	[GtkChild]
	private Gtk.Revealer revealer;

    [GtkChild]
    private Gtk.Stack stack;

    [GtkChild]
    private Gtk.Label revealer_label;

    [GtkChild]
    private Gtk.Popover sessionpopover;

	[GtkChild]
    private Gtk.Box box;

    [GtkChild]
    private Gtk.Button newsession;

    public Granite.Widgets.DatePicker session_start_date;

    public Granite.Widgets.TimePicker session_start_time;

    private Nico.Client client;

    private Nico.ClientAppMain main_frame;

	private GLib.List<string> locations;

	private Gtk.ComboBoxText locationsComboBox;

    public ClientView() {

		this.session_start_date = new Granite.Widgets.DatePicker();
        this.session_start_time = new Granite.Widgets.TimePicker();
        var create_new_session_button = new Gtk.Button.with_label("Create");
        create_new_session_button.clicked.connect(this.create_session);
        this.locationsComboBox = new Gtk.ComboBoxText();
        this.box.add(this.session_start_date);
        this.box.add(this.session_start_time);
        this.box.add(this.locationsComboBox);
	    this.box.add(create_new_session_button);
        this.box.show_all();

        // TODO: This is not working...
        this.revealer.reveal_child = false;
        this.revealer.set_transition_duration(500);
        this.revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
        Nico.ClientAppConnect connect_frame = new Nico.ClientAppConnect();
        connect_frame.connected_signal.connect(this.connected);
        connect_frame.error_signal.connect(this.reveal_error);
        this.stack.add_titled(connect_frame, "connect", "Connect to server");

		this.show_connect();

        this.destroy.connect(Gtk.main_quit);
        this.show_all();
         this.newsession.hide();
    }

    private void create_session() {
        this.client.resources.tabak   = ((Nico.ClientAppMain) this.stack.get_child_by_name("main")).tabak.active;
        this.client.resources.lighter = ((Nico.ClientAppMain) this.stack.get_child_by_name("main")).lighter.active;
        this.client.resources.filter  = ((Nico.ClientAppMain) this.stack.get_child_by_name("main")).filter.active;
        this.client.resources.papes   = ((Nico.ClientAppMain) this.stack.get_child_by_name("main")).papes.active;
	    ((GLib.DateTime) this.session_start_date.date).add_hours(this.session_start_time.time.get_hour());
        ((GLib.DateTime) this.session_start_date.date).add_hours(this.session_start_time.time.get_minute());
	    this.client.create_session((GLib.DateTime)this.session_start_date.date, "Wie immer");

	}

    [GtkCallback]
    private void show_newsession() {

		this.sessionpopover.show();

    }

    private void connected(Nico.Client client) {

		this.client = client;
        this.client.sessions_changed.connect(this.update_sessions);
		this.main_frame = new Nico.ClientAppMain(client);
        this.stack.add_titled(this.main_frame, "main", "ASSP");
        this.show_main();
	    this.client.locations_changed.connect(this.locations_changed);
        this.newsession.show();
        this.revealer.reveal_child = false;
        this.client.send_helo();

    }

	private void locations_changed(List<string> locations) {
		foreach(string location in locations) {

		}
	}

    private void reveal_error(string message) {

		this.revealer_label.label = message;
        this.revealer.reveal_child = true;

    }

        private void show_connect() {

            this.newsession.show_all();
            this.stack.set_visible_child_name("connect");

        }

        private void show_main() {

            this.stack.set_visible_child_name("main");

        }

    private void update_sessions(List<Nico.Session> sessions) {
		List<Nico.SessionView> currentSessionList = this.main_frame.get_sessions();
      	List<Nico.SessionView> toRemove = this.main_frame.get_sessions();

        foreach (Nico.Session s in sessions) {
			bool found = false;
            foreach (Nico.SessionView currentSessionView in currentSessionList) {
                if (currentSessionView == null) {
                    continue;
                }
				if(s.id == currentSessionView.id) {
		      		found = true;
                	currentSessionView.update(s);
                    toRemove.remove(currentSessionView);
					break;
                }
			}
			if(!found) {
				this.main_frame.add_session(s);
			}
		}
        foreach(Nico.SessionView sv in toRemove) {
            this.main_frame.remove_session(sv);
        }
    }

        public static void run() {
            new Nico.ClientView();
            Gtk.main();

        }
    }

    public static void main(string[] argv) {

        Gtk.init(ref argv);
        Nico.ClientView.run();
        return;

    }
}
